defmodule TestDirLoadServer do
    @moduledoc """
        动态加载测试目录下的模块, 并热更新
        ./test
    """
    require Logger
    use GenServer

    def start_link() do
        if Pango.RunMode.is_debug?() do
            GenServer.start_link(__MODULE__, [], name: __MODULE__)
        end
    end

    def get_state() do
        GenServer.call(__MODULE__, :get_state)
    end

    def init(_opts) do
        {:ok, %{}, {:continue, :init}}
    end

    def handle_continue(:init, state) do
        state = load_test_dir("./test", state)
        Process.send_after(self(), :refresh, 4000)
        {:noreply, state}
    end

    def handle_call(:get_state, _from, state) do
        {:reply, state, state}
    end
    def handle_call(_msg, _from, state) do
        {:reply, :ok, state}
    end

    def handle_cast(_msg, state) do
        {:noreply, state}
    end

    def handle_info(:refresh, state) do
        state = load_test_dir("./test", state)
        Process.send_after(self(), :refresh, 4000)
        {:noreply, state}
    end

    @doc """
        加载test文件夹里的模块
    """
    def load_test_dir(dir \\ "./test", state \\ %{}) do
        try do
            File.ls!(dir)
            |> Enum.reduce(
                   state,
                   fn filename, acc ->
                       file = dir <> "/" <> filename
                       if File.dir?(file) do
                           load_test_dir(file, acc)
                       else
                           old_ts = Map.get(acc, file)
                           ts = Map.get(File.lstat!(file, [:time]), :mtime)
                           if old_ts != ts do
                               IO.puts("TestDirLoadServer Refresh")
                               Code.eval_file(file)
                               Map.put(acc, file, ts)
                           else
                               acc
                           end
                       end
                   end
               )
        rescue
            err ->
                Logger.error("Load Error, reason: #{inspect(err)}")
                state
        end
    end


end